﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using ClearingRestartingAutomaton.Base;

namespace ClearingRestartingAutomaton
{
    public partial class LanguageForm : Form
    {
        public LanguageForm()
        {
            InitializeComponent();
        }

        public LanguageForm(Automaton automaton)
            : this()
        {
            this.automaton = automaton;

            if (this.automaton == null || 
                this.automaton.Instructions == null || 
                this.automaton.Instructions.Count == 0)
            {
                this.automatonRadioButton.Enabled = false;
            }
            else
            {
                this.automatonRadioButton.Checked = true;
            }
        }

        private Automaton automaton;
        private LanguageSampler languageSampler;

        private void buildButton_Click(object sender, EventArgs e)
        {
            if (!this.PrepareLanguageSampler()) { return; }
            int maxLength = (int)this.maximalLengthNumericUpDown.Value;
            int sampleMaxCount;
            int complementMaxCount;
            RichTextBox sampleTextBox;
            RichTextBox complementTextBox;
            if (this.complementCheckBox.Checked)
            {
                sampleMaxCount = (int)this.negativeMaximalCountNumericUpDown.Value;
                complementMaxCount = (int)this.positiveMaximalCountNumericUpDown.Value;
                sampleTextBox = this.negativeSamplesRichTextBox;
                complementTextBox = this.positiveSamplesRichTextBox;
            }
            else
            {
                sampleMaxCount = (int)this.positiveMaximalCountNumericUpDown.Value;
                complementMaxCount = (int)this.negativeMaximalCountNumericUpDown.Value;
                sampleTextBox = this.positiveSamplesRichTextBox;
                complementTextBox = this.negativeSamplesRichTextBox;
            }
            IEnumerable<string> languageSample;
            IEnumerable<string> complementSample;
            try
            {
                if (this.automatonRadioButton.Checked)
                {
                    languageSample = this.languageSampler.GetSamplesFromAutomaton(this.automaton, sampleMaxCount, maxLength);
                }
                else
                {
                    Regex regex = new Regex(this.regexTextBox.Text);
                    languageSample = this.languageSampler.GetSamplesFromRegex(regex, sampleMaxCount, maxLength);
                }
                complementSample = this.languageSampler.GetComplement(languageSample, complementMaxCount, maxLength);
            }
            catch (Exception exception)
            {
                MessageBox.Show("Exception: " + exception.Message, "Exception");
                return;
            }
            sampleTextBox.Clear();
            sampleTextBox.AppendText(String.Join(this.GetSeparator(), languageSample));
            complementTextBox.Clear();
            complementTextBox.AppendText(String.Join(this.GetSeparator(), complementSample));
        }

        private bool PrepareLanguageSampler()
        {
            this.languageSampler = new LanguageSampler();
            this.languageSampler.Alphabet.SetAlphabet(this.alphabetTextBox.Text);
            if (this.languageSampler.Alphabet.Letters.Count == 0)
            {
                MessageBox.Show("The alphabet is empty.", "Warning");
                return false;
            }
            else
            {
                return true;
            }
        }

        private string GetSeparator()
        {
            if (this.newLineRadioButton.Checked)
            {
                return Environment.NewLine;
            }
            else
            {
                return " ";
            }
        }

        private void clearPositiveSamplesButton_Click(object sender, EventArgs e)
        {
            this.positiveSamplesRichTextBox.Clear();
        }

        private void copyPositiveSamplesButton_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrWhiteSpace(this.positiveSamplesRichTextBox.Text))
            {
                Clipboard.SetText(this.positiveSamplesRichTextBox.Text);
            }
        }

        private void getPositiveSamplesButton_Click(object sender, EventArgs e)
        {
            if (!this.PrepareLanguageSampler()) { return; }
            string[] negativeSamples = this.negativeSamplesRichTextBox.Text.Split(
                new char[] { ' ', '\t', '\r', '\n', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
            IEnumerable<string> complementSample = this.languageSampler.GetComplement(negativeSamples, 
                (int)this.positiveMaximalCountNumericUpDown.Value, 
                (int)this.maximalLengthNumericUpDown.Value);
            this.positiveSamplesRichTextBox.Clear();
            this.positiveSamplesRichTextBox.AppendText(String.Join(this.GetSeparator(), complementSample));
        }

        private void clearNegativeSamplesButton_Click(object sender, EventArgs e)
        {
            this.negativeSamplesRichTextBox.Clear();
        }

        private void copyNegativeSamplesButton_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrWhiteSpace(this.negativeSamplesRichTextBox.Text))
            {
                Clipboard.SetText(this.negativeSamplesRichTextBox.Text);
            }
        }

        private void getNegativeSamplesButton_Click(object sender, EventArgs e)
        {
            if (!this.PrepareLanguageSampler()) { return; }
            string[] positiveSamples = this.positiveSamplesRichTextBox.Text.Split(
                new char[] { ' ', '\t', '\r', '\n', ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
            IEnumerable<string> complementSample = this.languageSampler.GetComplement(positiveSamples,
                (int)this.negativeMaximalCountNumericUpDown.Value,
                (int)this.maximalLengthNumericUpDown.Value);
            this.negativeSamplesRichTextBox.Clear();
            this.negativeSamplesRichTextBox.AppendText(String.Join(this.GetSeparator(), complementSample));
        }
    }
}
